﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System.Net;
using DailyPhoto.Common;

namespace DailyPhoto.Entities
{
    public class FacebookRepository : IRepository
    {

        public IEnumerable<Photo> Fetch()
        {
            var dic = new Dictionary<string, HashSet<string>>();

            var friends = ((JArray)Application.Config.friends).Select(x => x.ToString());
            var accessToken = Application.Config.accessToken.ToString();

            var tries = 3;
            var limit = 100;

            while (tries > 0)
            {
                try
                {
                    using (var wc = new WebClient())
                    {

                        var tagsQuery =
                            "https://graph.facebook.com/fql?q=SELECT+pid,subject+FROM+photo_tag+WHERE+subject+IN+({0})+LIMIT+{1}+OFFSET+{2}&access_token={3}";

                        int n = 1;
                        int offset;
                        JObject json = null;

                        while (json == null || json["data"].Count() > 0)
                        {
                            offset = (limit * n) + 1;

                            var u = string.Format(tagsQuery, string.Join(",", friends), limit, offset, accessToken);
                            var data = wc.DownloadString(u);

                            json = JObject.Parse(data);

                            foreach (var pair in json["data"])
                            {
                                var pid = pair["pid"].ToString();
                                var uid = pair["subject"].ToString();

                                if (!dic.ContainsKey(pid))
                                    dic[pid] = new HashSet<string>();

                                dic[pid].Add(uid);
                            }

                            n++;
                        }

                        var nonFriends = ((JArray)Application.Config.nonFriends).Select(y => y.ToString());
                        var mostFriends = dic
                        .Where(x => 
                        {
                            return x.Value.Count >= 2 && x.Value.All( z => !nonFriends.Contains(z) );
                        })
                        .Select( x =>
                        {
                            var p = new FBPhoto(x.Key);
                            p.RepositoryName = this.Name;
                            return p;
                        })
                        .Where(y => {
                            return !(new BlackList().GetEntriesOfRepository(this.Name).Select( z => z.PhotoId).Contains(y.PhotoId)); 
                        })
                        .ToArray();

                        return mostFriends;
                    }
                }
                catch (Exception ex)
                {
                    System.Threading.Thread.Sleep(2000);
                    tries--;

                    if (tries == 0)
                    {
                        throw new DailyphotoException("Error while fetching the Daily Photo: {0}", ex.Message);
                    }
                }
            }

            return new List<Photo>();
        }

        public string Name
        {
            get { return "Facebook"; }
        }
    }
}
